#pragma once

#include "config.h"
#ifdef USE_RF

#include <stdint.h>
#include "data_link_layer.h"

#define MAX_KNX_TELEGRAM_SIZE 263

class RfMediumObject;

class RfDataLinkLayer : public DataLinkLayer
{
#if defined(DeviceFamily_CC13X0)
        friend class RfPhysicalLayerCC1310;
#else
        friend class RfPhysicalLayerCC1101;
#endif
        using DataLinkLayer::_deviceObject;
        using DataLinkLayer::_platform;

    public:
        RfDataLinkLayer(DeviceObject& devObj, RfMediumObject& rfMediumObj, NetworkLayerEntity& netLayerEntity,
                        Platform& platform);

        void loop();
        void enabled(bool value);
        bool enabled() const;
        DptMedium mediumType() const override;

    private:
        bool _enabled = false;
        uint8_t _loopState = 0;

        uint8_t _buffer[512];

        uint8_t _frameNumber = 0;

        struct _tx_queue_frame_t
        {
            uint8_t* data;
            uint16_t length;
            _tx_queue_frame_t* next;
        };

        struct _tx_queue_t
        {
            _tx_queue_frame_t* front = NULL;
            _tx_queue_frame_t* back = NULL;
        } _tx_queue;

        RfMediumObject& _rfMediumObj;
#if defined(DeviceFamily_CC13X0)
        RfPhysicalLayerCC1310 _rfPhy;
#else
        RfPhysicalLayerCC1101 _rfPhy;
#endif
        void fillRfFrame(CemiFrame& frame, uint8_t* data);
        void addFrameTxQueue(CemiFrame& frame);
        bool isTxQueueEmpty();
        void loadNextTxFrame(uint8_t** sendBuffer, uint16_t* sendBufferLength);
        bool sendFrame(CemiFrame& frame);
        void frameBytesReceived(uint8_t* buffer, uint16_t length);
};

#endif
